﻿#define TEST

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Collections;
using System.Runtime.InteropServices;

using SuperMapLib;

namespace JR_RouteAlarm
{
    public partial class Form1 : Form
    {
        private Utility utl = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = openFileDialog1.FileName;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox2.Text = saveFileDialog1.FileName;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            button3.Enabled = false;
            button4.Enabled = true;

            try
            {
                Initialize();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);

                button3.Enabled = true;
                button4.Enabled = false;
                
                return;
            }

            try
            {
                MakeBuffer();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);

                button3.Enabled = true;
                button4.Enabled = false;

                return;
            }

            utl.ReleaseMemory();

            button3.Enabled = true;
            button4.Enabled = false;
        }

        private void Initialize()
        {
            Utility.datasourceAlias = "route"; //textBox1.Text.Substring(textBox1.Text.IndexOf(".sdb"));
            utl = new Utility(axSuperWorkspace1, textBox1.Text);
        }

        private void MakeBuffer()
        {
            soDatasets objDSs = null;

            objDSs = utl.objSource.Datasets;
            if (objDSs != null && objDSs.Count > 0)
            {
                soDataset objDS = null;
                soStrings objStrFields = null;

                objStrFields = new soStrings();
                objStrFields.Add(Route.FEATURE_CD);
                objStrFields.Add(Route.DAIBUN_CD);
                objStrFields.Add(Route.TSUUSHO_CD);

                for (int i = 1; i <= objDSs.Count; i++)
                {
                    objDS = objDSs[i];
                    if (!objDS.Name.Contains(Utility.BUFFER_TITLE))
                    {
                        try
                        {
                            MakeRoutes(objDS as soDatasetVector, objStrFields);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);

                            Marshal.ReleaseComObject(objStrFields);
                            objStrFields = null;
                            Marshal.ReleaseComObject(objDS);
                            objDS = null;
                            Marshal.ReleaseComObject(objDSs);
                            objDSs = null;

                            return;
                        }

                        try
                        {
                            BuildBuffer(objDS.Name + Utility.BUFFER_TITLE);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);

                            Marshal.ReleaseComObject(objStrFields);
                            objStrFields = null;
                            Marshal.ReleaseComObject(objDS);
                            objDS = null;
                            Marshal.ReleaseComObject(objDSs);
                            objDSs = null;

                            return;
                        }
                    }
                }

                Marshal.ReleaseComObject(objStrFields);
                objStrFields = null;
                Marshal.ReleaseComObject(objDS);
                objDS = null;
                Marshal.ReleaseComObject(objDSs);
                objDSs = null;
            }
        }

        private void MakeRoutes(soDatasetVector objDSV, soStrings objStrFields)
        {
            soRecordset objRS = null;

            objRS = objDSV.Query("-1 < 0", false, objStrFields, 
                "group by " + Route.FEATURE_CD + ", " + Route.DAIBUN_CD + ", " + Route.TSUUSHO_CD);

            if (objRS != null && objRS.RecordCount > 0)
            {
                if (!objRS.IsBOF())
                {
                    objRS.MoveFirst();
                }

                IRoute route = new Route();
#if TEST
                for (int j = 0; j < objRS.RecordCount / 100; objRS.MoveNext(), j++)
#else
                for (; !objRS.IsEOF(); objRS.MoveNext())
#endif
                {
                    try
                    {
                        route.MakeBufferForRoute(objDSV, objRS);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);

                        objRS.Close();
                        Marshal.ReleaseComObject(objRS);
                        objRS = null;

                        return;
                    }
                }

                objRS.Close();
                Marshal.ReleaseComObject(objRS);
                objRS = null;
            }
        }

        private void BuildBuffer(string dsName)
        {
            soDataset objDS = null;

            if (!utl.objSource.IsAvailableDatasetName(dsName))
            {
                if (!utl.objSource.DeleteDataset(dsName))
                {
                    //MessageBox.Show("Dataset delete failed!");
                    throw new Exception("Dataset delete failed!");

                    return;
                }
            }

            objDS = utl.objSource.CreateDataset(
                dsName, seDatasetType.scdRegion, seDatasetOption.scoDefault, null);
            if (objDS!= null)
            {
                soDatasetVector objDatasetV = null;
                soRecordset objRecords = null;

                objDatasetV = objDS as soDatasetVector;
                objRecords = objDatasetV.Query("-1 < 0", true, null, "");
                if (objRecords != null)
                {

#if TEST
                    int i = 0, j = 0;
#endif
                    soGeoLine objLine = null;
                    soGeometry objMetry = null;
                    foreach (object arr in Utility.routeFtrWithLn.Values)
                    {
                        foreach (object obj in arr as ArrayList)
                        {
                            objLine = obj as soGeoLine;
                            objMetry = Utility.routeLnWithBfr[objLine] as soGeometry;
#if TEST
                            if (i = objRecords.AddNew(objMetry, false) != 0)
                            {
                                Console.WriteLine("{0}, {1}", ++j, i);
#else
                            if (objRecords.AddNew(objMetry, false) != 0)
                            {
#endif
                                if (objRecords.Update() == -1)
                                {
                                    throw new Exception("Build buffer failed!");

                                    Marshal.ReleaseComObject(objMetry);
                                    objMetry = null;
                                    Marshal.ReleaseComObject(objLine);
                                    objLine = null;
                                    objRecords.Close();
                                    Marshal.ReleaseComObject(objRecords);
                                    objRecords = null;
                                    Marshal.ReleaseComObject(objDatasetV);
                                    objDatasetV = null;

                                    return;
                                }
                            }
                            else
                            {
                                throw new Exception("Add new failed!");

                                Marshal.ReleaseComObject(objMetry);
                                objMetry = null;
                                Marshal.ReleaseComObject(objLine);
                                objLine = null;
                                objRecords.Close();
                                Marshal.ReleaseComObject(objRecords);
                                objRecords = null;
                                Marshal.ReleaseComObject(objDatasetV);
                                objDatasetV = null;

                                return;
                            }
                        }
                    }
                    //utl.objSource.Flush(dsName);

                    Marshal.ReleaseComObject(objMetry);
                    objMetry = null;
                    Marshal.ReleaseComObject(objLine);
                    objLine = null;
                    objRecords.Close();
                    Marshal.ReleaseComObject(objRecords);
                    objRecords = null;
                    Marshal.ReleaseComObject(objDatasetV);
                    objDatasetV = null;
                }

                Marshal.ReleaseComObject(objDS);
                objDS = null;
            }
        }
    }
}